package shop.ynubeggar.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import shop.ynubeggar.exception.CustomException;
import shop.ynubeggar.mapper.CategoryMapper;
import shop.ynubeggar.mapper.ProductMapper;
import shop.ynubeggar.model.dataobject.ProductDO;
import shop.ynubeggar.model.dataobject.ProductOrderDO;
import shop.ynubeggar.model.valueobject.ProductVO;
import shop.ynubeggar.request.CreateProductRequest;
import shop.ynubeggar.request.UpdateProductRequest;
import shop.ynubeggar.service.AdminProductService;
import shop.ynubeggar.utils.ImageUtils;
import shop.ynubeggar.utils.oss.MinioTemplate;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;


@Slf4j
@Service
@DS("yeat_product")
public class AdminProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO>  implements AdminProductService {

    @Resource
    ProductMapper productMapper;
    @Resource
    CategoryMapper categoryMapper;

    @Resource
    MinioTemplate minioTemplate;
    @Resource
    AdminCategoryServiceImpl adminCategoryService;

    @Override
    @DS("yeat_product")
    public void createProduct(CreateProductRequest createProductRequest) {
        if (createProductRequest.getCoverImg().isBlank()) {
            throw new CustomException(HttpStatus.NOT_FOUND, "product CoverImg is null");
        }
//        如果类别不存在
        if (categoryMapper.selectById(createProductRequest.getCategory()) == null) {
            log.info("category does not exist: {}", createProductRequest);
            throw new CustomException(HttpStatus.NOT_FOUND, "category does not exist");
        }
        MultipartFile multipartFile = ImageUtils.base64ToMultipartFile(createProductRequest.getCoverImg());

        // 存文件到oss，返回文件路径
        String imgPath = minioTemplate.putObject(multipartFile).getOssFilePath();

        createProductRequest.setCoverImg(imgPath);

        ProductDO productDO = new ProductDO(createProductRequest);

        int res = productMapper.insert(productDO);
        if (res == 0) {
            throw new CustomException(HttpStatus.NOT_FOUND, "create product error");
        }
        log.info("res:{},insert success:{}", res, productDO);


    }

    /**
     * 根据id删除商品
     *
     * @param productId
     */
    @Override
    public void deleteProduct(long productId) {
        if (!removeById(productId)) {
            log.error("deleteProduct:res:false,id:{}", productId);
            throw new CustomException(HttpStatus.NOT_FOUND, "product(id=" + productId + " does not exist");
        }
        log.info("deleteProduct:res:true,id:{}", productId);
    }

    /**
     * 分页查找商品
     *
     * @param page
     * @param size
     * @param categoryId
     * @return
     */
    @Override
    public Map<String, Object> findPage(int page, int size, int categoryId) {
        IPage<ProductDO> productDOPage = null;
        if (categoryId == -1) {
            productDOPage = page(new Page<>(page, size));
        } else {
            productDOPage = page(new Page<>(page, size), new QueryWrapper<ProductDO>().eq("category", categoryId));
        }
        if (productDOPage == null) {
            throw new CustomException(HttpStatus.NOT_FOUND, "no records");
        }

        Map<String, Object> map = new HashMap<>(3);
        map.put("total_page", productDOPage.getPages());
        map.put("total_record", productDOPage.getTotal());
        map.put("data", productDOPage.getRecords().stream().map(obj -> {
            ProductVO vo = new ProductVO();
            BeanUtil.copyProperties(obj, vo);
            vo.setStock(obj.getStock() - obj.getLockStock());
            return vo;
        }).collect(Collectors.toList()));
        return map;
    }

    /**
     * 根据id查找商品
     *
     * @param productId
     * @param categoryId
     * @return
     */
    @Override
    public ProductVO findOne(long productId, int categoryId) {
        ProductDO productDO = null;
        if (categoryId == -1) {
            productDO = getById(productId);
        } else {
            productDO = getOne(new QueryWrapper<ProductDO>().eq("id", productId).eq("category", categoryId));
        }
        if (productDO == null) {
            log.error("findOrder:res:false,id:{}", productId);
            throw new CustomException(HttpStatus.NOT_FOUND, "order(id=" + productId + " does not exist");
        }
        ProductVO productVO = new ProductVO();
        BeanUtil.copyProperties(productDO, productVO);
        return productVO;
    }

    /**
     * 根据id更新商品
     *
     * @param productId
     * @param updateProductRequest
     */
    @Override
    public void updateOneProduct(long productId, UpdateProductRequest updateProductRequest) {
        ProductDO productDO = getById(productId);
        if (productDO == null) {
            log.error("updateProduct:res:false,id:{}", productId);
            throw new CustomException(HttpStatus.NOT_FOUND, "product(id=" + productId + " does not exist");
        }
        BeanUtil.copyProperties(updateProductRequest, productDO);
        updateById(productDO);
        log.error("updateProduct:res:true,id:{},product:{}", productId, productDO);
    }

    @Override
    public void updateProductStock(long productId, int stockAddNum) {
        ProductDO productDO = getById(productId);
        if (productDO == null) {
            log.error("updateProduct:res:false,id:{}", productId);
            throw new CustomException(HttpStatus.NOT_FOUND, "product(id=" + productId + " does not exist");
        }
        productDO.setStock(productDO.getStock()+stockAddNum);
        updateById(productDO);
        log.error("updateProduct:res:true,id:{},product:{}", productId, productDO);
    }

    @Override
    public void updateOneProductImg(long id, String base64String) {

        MultipartFile multipartFile = ImageUtils.base64ToMultipartFile(base64String);

        // 存文件到oss，返回文件路径
        String imgPath = minioTemplate.putObject(multipartFile).getOssFilePath();

        ProductDO productDO = getById(id);
        productDO.setCoverImg(imgPath);

        if (updateById(productDO)) {
            log.info("res:false,update product img success:{}", productDO);
            throw new CustomException(HttpStatus.NOT_FOUND, "update product img error");
        }
        log.info("res:true,update product img success:{}", productDO);
    }

}
